package com.free.fs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.free.fs.common.constant.CommonConstant;
import com.free.fs.common.template.DocTemplate;
import com.free.fs.mapper.DocMapper;
import com.free.fs.model.DocPojo;
import com.free.fs.service.PublicDocService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 公共文档服务实现
 *
 * @author dinghao
 * @date 2024/01/01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PublicDocServiceImpl implements PublicDocService {

    private final DocMapper docMapper;
    private final DocTemplate docTemplate;

    @Value("${fs.files-server.doc.uploadDir:D:/data/free-fs/doc/}")
    private String docUploadDir;

    @Override
    public List<DocPojo> getDocList(String path) {
        log.info("查询文档列表，路径: {}", path);
        
        LambdaQueryWrapper<DocPojo> wrapper = new LambdaQueryWrapper<>();
        // 修改：同时返回文档和目录
        // wrapper.eq(DocPojo::getIsDir, false); // 注释掉这行，不再只显示文档
        wrapper.orderByDesc(DocPojo::getPutTime);
        
        // 如果路径为空，查询所有文档和目录
        if (path == null || path.trim().isEmpty()) {
            log.info("查询所有文档和目录");
        } else {
            // 处理特定分类路径
            Long parentId = parsePathToParentId(path);
            wrapper.eq(DocPojo::getParentId, parentId);
            log.info("查询特定分类下的文档和目录，父目录ID: {}", parentId);
        }
        
        List<DocPojo> docs = docMapper.selectList(wrapper);
        log.info("查询到文档和目录数量: {}", docs.size());
        
        // 为每个文档和目录添加额外的显示信息
        for (DocPojo doc : docs) {
            if (doc.getIsDir()) {
                // 目录处理
                doc.setType("directory");
                log.debug("发现目录: {}", doc.getName());
            } else {
                // 文档处理
                doc.setSize(doc.getSize());
                doc.setType(getFileTypeIcon(doc.getSuffix()));
                log.debug("发现文档: {}", doc.getName());
            }
        }
        
        return docs;
    }

    /**
     * 获取文档分类列表（根目录下的所有子目录）
     */
    @Override
    public List<DocPojo> getDocCategories() {
        // 查询根目录下的所有子目录
        LambdaQueryWrapper<DocPojo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocPojo::getParentId, CommonConstant.ROOT_PARENT_ID);
        wrapper.eq(DocPojo::getIsDir, true); // 只显示目录
        wrapper.orderByAsc(DocPojo::getName);
        
        List<DocPojo> categories = docMapper.selectList(wrapper);
        
        // 为每个分类添加统计信息和子目录
        for (DocPojo category : categories) {
            // 统计该分类下的文档数量
            LambdaQueryWrapper<DocPojo> countWrapper = new LambdaQueryWrapper<>();
            countWrapper.eq(DocPojo::getParentId, category.getId());
            countWrapper.eq(DocPojo::getIsDir, false);
            Long docCount = docMapper.selectCount(countWrapper);
            
            // 设置文档数量（使用size字段存储）
            category.setSize(docCount);
            
            // 加载该分类下的子目录
            LambdaQueryWrapper<DocPojo> subDirWrapper = new LambdaQueryWrapper<>();
            subDirWrapper.eq(DocPojo::getParentId, category.getId());
            subDirWrapper.eq(DocPojo::getIsDir, true); // 只查询目录
            subDirWrapper.orderByAsc(DocPojo::getName);
            
            List<DocPojo> subDirectories = docMapper.selectList(subDirWrapper);
            
            // 为子目录设置类型
            for (DocPojo subDir : subDirectories) {
                subDir.setType("directory");
            }
            
            // 设置子目录列表
            category.setSubDirectories(subDirectories);
            
            log.info("分类 {} 有 {} 个文档和 {} 个子目录", category.getName(), docCount, subDirectories.size());
        }
        
        return categories;
    }

    @Override
    public void downloadDoc(Long docId, String fileName, HttpServletResponse response) {
        DocPojo doc = docMapper.selectById(docId);
        if (doc == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        
        // 如果提供了自定义文件名，设置下载文件名
        if (fileName != null && !fileName.trim().isEmpty()) {
            try {
                // 确保文件名包含正确的扩展名
                String finalFileName = fileName;
                if (doc.getSuffix() != null && !doc.getSuffix().isEmpty()) {
                    if (!finalFileName.toLowerCase().endsWith("." + doc.getSuffix().toLowerCase())) {
                        finalFileName = finalFileName + "." + doc.getSuffix();
                    }
                }
                
                // 设置下载文件名，处理中文编码
                String encodedFileName = java.net.URLEncoder.encode(finalFileName, "UTF-8");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
                log.info("设置下载文件名: {}", finalFileName);
            } catch (Exception e) {
                log.warn("设置下载文件名失败: {}", e.getMessage());
            }
        }
        
        // 使用现有的下载逻辑
        docTemplate.download(doc.getUrl(), response);
    }

    @Override
    public void downloadDocByPath(String docPath, String fileName, HttpServletResponse response) {
        // 根据文档路径查找文档
        LambdaQueryWrapper<DocPojo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocPojo::getUrl, docPath);
        DocPojo doc = docMapper.selectOne(wrapper);

        if (doc == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // 如果提供了自定义文件名，设置下载文件名
        if (fileName != null && !fileName.trim().isEmpty()) {
            try {
                log.info("开始设置自定义文件名: {}", fileName);
                // 确保文件名包含正确的扩展名
                String finalFileName = fileName;
                if (doc.getSuffix() != null && !doc.getSuffix().isEmpty()) {
                    if (!finalFileName.toLowerCase().endsWith("." + doc.getSuffix().toLowerCase())) {
                        finalFileName = finalFileName + "." + doc.getSuffix();
                    }
                }
                
                // 设置下载文件名，处理中文编码
                String encodedFileName = java.net.URLEncoder.encode(finalFileName, "UTF-8");
                String disposition = "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName;
                response.setHeader("Content-Disposition", disposition);
                log.info("设置下载文件名: {}, 编码后: {}, Content-Disposition: {}", finalFileName, encodedFileName, disposition);
            } catch (Exception e) {
                log.warn("设置下载文件名失败: {}", e.getMessage());
            }
        } else {
            log.info("没有提供自定义文件名，使用默认文件名");
        }
        
        docTemplate.download(doc.getUrl(), response);
    }

    /**
     * 解析路径为父目录ID
     */
    private Long parsePathToParentId(String path) {
        if (path == null || path.trim().isEmpty()) {
            return CommonConstant.ROOT_PARENT_ID;
        }
        
        // 处理分类路径格式：category_123
        if (path.startsWith("category_")) {
            try {
                String categoryIdStr = path.substring("category_".length());
                return Long.parseLong(categoryIdStr);
            } catch (NumberFormatException e) {
                log.warn("Invalid category path: {}", path);
                return CommonConstant.ROOT_PARENT_ID;
            }
        }
        
        // 其他路径处理逻辑...
        return CommonConstant.ROOT_PARENT_ID;
    }

    /**
     * 根据文件后缀获取文件类型图标
     */
    private String getFileTypeIcon(String suffix) {
        if (suffix == null) {
            return "file";
        }
        
        String lowerSuffix = suffix.toLowerCase();
        
        // 图片文件
        if (lowerSuffix.matches("png|jpg|jpeg|gif|bmp|svg|ico")) {
            return "image";
        }
        // 文档文件
        else if (lowerSuffix.matches("pdf|doc|docx|txt|md")) {
            return "document";
        }
        // 表格文件
        else if (lowerSuffix.matches("xls|xlsx|csv")) {
            return "spreadsheet";
        }
        // 演示文件
        else if (lowerSuffix.matches("ppt|pptx")) {
            return "presentation";
        }
        // 压缩文件
        else if (lowerSuffix.matches("zip|rar|7z|tar|gz")) {
            return "archive";
        }
        // 可执行文件
        else if (lowerSuffix.matches("exe|msi|dmg|pkg|deb|rpm|app|appx")) {
            return "executable";
        }
        // 移动应用包
        else if (lowerSuffix.matches("apk|ipa")) {
            return "mobile-app";
        }
        // 音视频文件
        else if (lowerSuffix.matches("mp3|mp4|avi|mov|wav")) {
            return "media";
        }
        // 代码文件
        else if (lowerSuffix.matches("java|js|py|php|vue|css|sql|xml|html|htm")) {
            return "code";
        }
        // 默认文件图标
        else {
            return "file";
        }
    }
}